home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / misc / ddli2_02.lha / qst.c < prev    next >
C/C++ Source or Header  |  1993-04-04  |  3KB  |  154 lines

  1. /* QST.C  Copyright (C) 1993 Fergus Patrick Duniho */
  2.  
  3. #define MAXLINE 256
  4.  
  5. typedef struct qnode {
  6.     int p[2];
  7.     int num, ans, first;
  8.     char *Qtext, *Atext[2];
  9.     struct qnode *pv, *nx;
  10. } qst;
  11.  
  12. qst *RND_QList (qst *Q, int size);
  13. char *Get_QList (char *fname, qst *Q, int size);
  14. void AskQuestions (qst *Q, int col);
  15. int AskQ (qst *Q, int col);
  16. char get_answer(int col);
  17. qst *new_qnode (int num);
  18.  
  19. qst *new_qnode (int num) {
  20.     qst *node;
  21.  
  22.     if ((node = (qst *)malloc(sizeof(qst))) == NULL) {
  23.       perror ("Malloc can't allocate enough memory for a new qnode.\n");
  24.       exit (2);
  25.    }
  26.    node->ans = -1;
  27.    node->num = num;
  28.    return node;
  29. }
  30.  
  31. /* Get_QList: Reads questions from a file into a linked list.
  32.    Returns the version # string from the beginning of the
  33.    questions file. */
  34.  
  35. char *Get_QList (char *fname, qst *Q, int size) {
  36.     FILE *fptr;
  37.     int i, j;
  38.     char *V;
  39.     qst *S;
  40.  
  41.     S = Q;
  42.     RdOpen (fptr, fname);
  43.     V = clone_line(fptr, MAXLINE);
  44.     for (i = 1; i <= size; i++) {
  45.     Q->nx = new_qnode(i);
  46.     Q->nx->pv = Q;
  47.     Q = Q->nx;
  48.     Q->Qtext = clone_line(fptr, MAXLINE);
  49.     for (j = 0; j < 2; j++) {
  50.         Q->p[j] = fgetp(fptr);
  51.         Q->Atext[j] = clone_line(fptr, MAXLINE);
  52.     }
  53.     }
  54.     fclose (fptr);
  55.     Q->nx = S;
  56.     return V;
  57. }
  58.  
  59. /* nth_qnode: Returns the nth member of a linked list of qst nodes. */
  60.  
  61. qst *nth_qnode (qst *Q, unsigned int n) {
  62.     while (n--)
  63.     Q = Q->nx;
  64.     return Q;
  65. }
  66.  
  67. /* RND_QList: Randomizes a linked list of questions. */
  68.  
  69. qst *RND_QList (qst *Q, int size) {
  70.     qst *S, *L, *N, *SN;
  71.     unsigned int i;
  72.  
  73.     SN = N = new_qnode(0);  /* Randomizes Question Order */
  74.     S = Q;
  75.     for (; size; size--) {
  76.     i = (rand() % size) + 1;
  77.     L = nth_qnode(S, i);
  78.     L->nx->pv = L->pv;
  79.     L->pv->nx = L->nx;
  80.     N->nx = L;
  81.     L->pv = N;
  82.     N = L;
  83.     N->first = rand() % 2; /* Randomizes Answer Order */
  84.     }
  85.     free (S);
  86.     N->nx = SN;
  87.     SN->pv = N;
  88.     return SN;
  89. }
  90.  
  91. void AskQuestions (qst *Q, int col) {
  92.     int more = 1, flag = 1, num;
  93.  
  94.     while (more) {
  95.     for (Q = Q->nx, num = 1; Q->num > 0; Q = Q->nx, num++) {
  96.         if ((Q->ans != -1) && flag)
  97.         continue;
  98.         flag = 1;
  99.         printf ("\nQuestion #%d\n", num);
  100.         if (AskQ(Q, col)) {
  101.         Q = Q->pv->pv;
  102.         flag = 0;
  103.         num -= 2;
  104.         if (num < 0) num = 0;
  105.         }
  106.     }
  107.     more = 0;
  108.     for (Q = Q->nx; Q->num > 0; Q = Q->nx)
  109.         if (Q->ans == -1) more = 1;
  110.     }
  111. }
  112.  
  113. /* AskQ: Asks a single question. */
  114.  
  115. int AskQ (qst *Q, int col) {
  116.     char A;
  117.  
  118.     wrapwrite (stdout, 0, 0, col, Q->Qtext, 0);
  119.     wrapwrite (stdout, 0, 4, col, "(A)", Q->Atext[0], 0);
  120.     puts (" ... Or");
  121.     wrapwrite (stdout, 0, 4, col, "(B)", Q->Atext[1], 0);
  122.     if ((A = get_answer(col)) < 2)
  123.     Q->ans = Q->p[A];
  124.     else if (A == 4)
  125.     exit (2);
  126.     return A == 3;
  127. }
  128.  
  129. char get_answer(int col) {
  130.     char c;
  131.  
  132.     for (;;) {
  133.     c = fgetc(stdin);
  134.     while (fgetc(stdin) != '\n');
  135.     if (islower(c))
  136.         c = toupper(c);
  137.     if (c == 'A')
  138.         return 0;
  139.     if (c == 'B')
  140.         return 1;
  141.     if (c == 'S')
  142.         return 2;
  143.     if (c == 'P')
  144.         return 3;
  145.     if (c == 'Q')
  146.         return 4;
  147.     wrapwrite (stdout, 0, 0, col,
  148.         "Answer with an A or a B.\n",
  149.         "P = Go back to Previous question\n",
  150.         "Q = Quit\n",
  151.         "S = Skip until later.\n", 0);
  152.     }
  153. }
  154.